﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SNWordLParser
{
    class Syntax{
        private List<TokenType> list;//这个是token序列的引用
        public  Global global;
        public  TokenType token;//记录当前的token
        private string temp_name;
        int line0;//行号
        static int indentno=0;//记录缩进,初始化是0
        static void  increase(){ indentno+=1;}
        static void decrease() { indentno -=1;}
        int fp_num=0;    /*输出时记录token个数的变量*/
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="global"></param>
        /// <param name="list"></param>
        public Syntax(Global global,List<TokenType> list)
        {
            fp_num = 0;
            this.global = global;
            global.operateError = false;
            this.list = list;
        }
        //////////////////////////////////////////////////////////////语法分析函数///////////////////////////////////////////////
        /// <summary>
        /// 语法分析函数
        /// </summary>
        /// <returns></returns>
        public treeNode parse()
        {

            fp_num = 0;    /*输出时记录token个数的变量*/
            global.operateError = false;
            treeNode t = null;
            ReadNextToken();
            t = program();
            if (token.Lex != LexType.ENDFILE1)
                printError("Code ends before file\n");
            return t;
        }

        public void printError() 
        {
            window.WriteLine("有错误");
        }

        public void printError(string str)
        {
            window.WriteLine(str);
        }

        public void exit()
        {
            window.WriteLine("exit 还没有实现");
        }

        treeNode newNode() 
        { 
            treeNode t=new treeNode();
            int i;
            if (t == null)
            {
                printError();
                global.operateError = true;
                exit();
            }
            else
            {
                for (i = 0; i < treeNode.MAXCHILDREN; i++) 
                    t.child[i] = null;
                t.sibling = null;
                t.lineno = line0;//当前节点的行号设置为当前行号
                for (i = 0; i < 10; i++)
                {
                    t.name[i] = null;
                }
                //  Window.WriteLine("newNode  74");
            }
            return t;
        }

        treeNode newSpecificNode(NodeKind kind) 
        {
            treeNode t = newNode();
            t.nodekind = kind;
            return t;
        }
        treeNode newStmtNode(StmtKind kind)
        {
            treeNode t=newNode();
            t.nodekind = NodeKind.StmtK;
            t.kind.stmt = kind;
            return t;
        }
        treeNode newExpNode(ExpKind kind)
        {
            treeNode t = newNode();
            t.nodekind =NodeKind.ExpK;
            t.kind.exp = kind;
            return t;
        }

        public void setList(List<TokenType> li) 
        {
            this.list = li; 
        }

        public List<TokenType> getList() 
        {
            return list; 
        }

        public void setListnull() 
        { 
            list = null; 
        }

        public void ReadNextToken() 
        {
            if (list == null)
            {
                window.WriteLine("list is null");
            }
            else
            {
                while (true) 
                {
                    if (list[fp_num].Lex == LexType.CRT) fp_num++;
                    else break;
                }
                token=list[fp_num];
                fp_num++;
            }
        }

        //void printTab(int tabnum){
        //     for(int i=0;i<tabnum;i++)
        //     Window.Write("    ");
        //}

        void  printSpaces()
        { 
            int i;
            for (i=0;i<indentno;i++)	
            window.Write("  ");	
        }
////////////////////////////////////////////////////////////////////////////打印结果
        public void printTree(treeNode tree)
        {
            int i;
            increase(); 
            while (tree !=null)
            {
                if (tree.lineno != 0)
                printSpaces();
  
                switch ( tree.nodekind) 
                { 
                    case NodeKind.ProK : 
                        window.Write("程序的结构如下："); 
                        break;
                    case NodeKind.PheadK:
                        {
                            //Window.Write("  程序的开始部分： "+"PheadK");
                            window.Write("程序名："+tree.name[0]);
                        }
                        break;
                    case NodeKind.DecK:
                        {
                            //Window.WriteLine( "声明部分：");
                            //if (tree.attr.ProcAttr.paramt == ParamType.varparamType)
                            //    Window.Write("var param:");
                            //if (tree.attr.ProcAttr.paramt == ParamType.valparamType)
                            //    Window.Write("value param:");
                            switch (tree.kind.dec)
                            {
                                case DecKind.ArrayK:
                                    {
                                        window.Write("数组类型定义");
                                        window.Write("下界：" + tree.attr.ArrayAttr.low + " ");
                                        window.Write("上界：" + tree.attr.ArrayAttr.up + " ");
                                        if (tree.attr.ArrayAttr.childtype == DecKind.CharK)
                                            window.Write("成员类型：字符");
                                        else if (tree.attr.ArrayAttr.childtype == DecKind.IntegerK)
                                            window.Write("成员类型：整数");
                                    };
                                    break;
                                case DecKind.CharK:
                                    window.Write("字符类型");
                                    break;
                                case DecKind.IntegerK:
                                    window.Write("整数类型 ");
                                    break;
                                case DecKind.RecordK:
                                    window.Write("记录类型 ");
                                    break;
                                case DecKind.IdK:
                                    window.Write("自定义类型 ");
                                    window.Write(tree.attr.type_name);
                                    break;
                                default:
                                    window.Write("Error1!");
                                    global.operateError = true;
                                    break;
                            }   //  switch (tree.kind.dec)

                            if (tree.idnum != 0)
                            {
                                int iu= 0;
                                for (; iu<= (tree.idnum); iu++)
                                {
                                    window.Write(" "+tree.name[iu]+" ");
                                }
                            }   //  if
                            else
                            {
                                window.Write("wrong!no var!\n");
                                global.operateError = true;
                            }    //  else
                        }
                        break;  //  case NodeKind.DecK:
                    case NodeKind.TypeK:
                        window.Write("类型声明 ");
                        break;
	  
                    case NodeKind.VarK:
                        window.Write("变量声明 ");
                        //if(tree.table[0]!=null)
                        //    Window.WriteLine("%d  %d  ",tree.table[0].attrIR.More.VarAttr.off,tree.table[0].attrIR.More.VarAttr.level);
                        break;
	  
                    case NodeKind.ProcDecK: 
                        window.Write("函数声明  ");
                        window.Write(tree.name[0]);
                        //if(tree.table[0]!=null)
                        //    Window.WriteLine("%d %d %d  ",tree.table[0].attrIR.More.ProcAttr.mOff,tree.table[0].attrIR.More.ProcAttr.nOff,tree.table[0].attrIR.More.ProcAttr.level);
                        break;
	  
                    case NodeKind.StmLK:
                        window.Write("语句序列 ");break;
	  
                    case NodeKind.StmtK: 
                        { 
                            // Window.Write(" 一个语句 ");
                            switch (tree.kind.stmt)
                            {
                                case StmtKind.IfK:
                                    window.Write("If语句 ");
                                    break;
                                case StmtKind.WhileK:
                                    window.Write("While语句 ");
                                    break;

                                case StmtKind.AssignK:
                                    window.Write("赋值语句 ");
                                    break;

                                case StmtKind.ReadK:
                                    window.Write("输入语句 ");
                                    window.Write( tree.name[0]);
                                    //if(tree.table[0]!=null)
                                    //    Window.WriteLine("%d   %d  ",tree.table[0].attrIR.More.VarAttr.off,tree.table[0].attrIR.More.VarAttr.level);
                                    break;

                    case StmtKind.WriteK:
		               window.Write("输出语句 ");break;

                    case StmtKind.CallK:
		               window.Write("函数调用语句 ");
				       window.Write( tree.name[0]);
				       break;

                    case StmtKind.ReturnK:
		               window.Write( "返回语句 ");break;
     
			      default: 
				    window.Write("Error2!");
				    global.operateError = true;
                    break;
			    }
              };break;
	      case NodeKind.ExpK: 
		      { 
                  //Window.Write( " 表达式 ");
		        switch (tree.kind.exp)
                {
                    case ExpKind.OpK:{
                        window.Write( "操作符 ");
			            switch(tree.attr.ExpAttr.op)
                        {
                            case LexType.EQ: window.Write(  "="); break;
                            case LexType.LT: window.Write(  "<"); break;
                            case LexType.PLUS: window.Write(  "+"); break;
                            case LexType.MINUS: window.Write(  "-"); break;
                            case LexType.TIMES: window.Write(  "*"); break;
                            case LexType.OVER: window.Write(  "/"); break;  
                          default: 
						      window.Write("333333333333333333333333333333333Error!");
						      global.operateError = true;
                              break;
					    }

                        if (tree.attr.ExpAttr.varkind == VarKind.ArrayMembV)
					    {
						    window.Write("数组成员 ");
						    window.Write( tree.name[0]);
					    }
                      };break;
                    case ExpKind.ConstK:
				        window.Write( "常量 ");
                        //switch(tree.attr.ExpAttr.varkind)
                        //{
                        //    case VarKind.IdV:
                        //    Window.Write("标识符 ");
                        //    Window.Write( tree.name[0]);
                        //    break;
                        //    case VarKind.FieldMembV:
                        //    Window.Write("记录域成员  ");
                        //    Window.Write( tree.name[0]);
                        //    break;
                        //    case VarKind.ArrayMembV:
                        //    Window.Write("数组成员  ");
                        //    Window.Write( tree.name[0]);
                        //    break;
                        //    default: 
                        //        Window.Write("var type global.operateError!");
                        //        global.operateError = true;
                        //        break;
                        //}
					
					    window.Write("  "+tree.attr.ExpAttr.val);
					    break;
                    case ExpKind.VariK:
		              // Window.Write( "变量 ");
                       switch(tree.attr.ExpAttr.varkind)
				       {
                           case VarKind.IdV:
					        window.Write("标识符 ");
						    window.Write( tree.name[0]);
						    break;
                           case VarKind.FieldMembV:
					        window.Write("域成员变量 ");
					        window.Write( tree.name[0]);
						    break;
                           case VarKind.ArrayMembV:
					        window.Write("数组成员变量 ");
						    window.Write( tree.name[0]);
						    break;
						    default: 
							    window.Write("22222222222222222222222Error!");
							    global.operateError = true;
                                break;
				       }
                       //if(tree.table[0]!=null)
                       //    Window.Write("%d   %d  ",tree.table[0].attrIR.More.VarAttr.off,tree.table[0].attrIR.More.VarAttr.level);

				       break;
                  default: 
				      window.Write("444444444444444444444444444444444Error4!");
				      global.operateError = true;
                      break;
			    }
		      };break;
       default: 
	       window.Write("555555555555555555555555555555555555Error5!");
	       global.operateError = true;
           break;
       }
       window.Write("\n");
       increase();
       for (i = 0; i < treeNode.MAXCHILDREN; i++)
           printTree(tree.child[i]);
       decrease();
       tree = tree.sibling;
      }
   decrease();
}
//match 函数//////////////////////////////////////////////匹配函数///////////////////////////////////////////////////////
void match(LexType expected)
{
    if (token.Lex == expected)
    {
        ReadNextToken();
        line0 = token.lineshow;//将当当前行号赋值给line0
    }
    else
    {
        printError("Not match error(匹配错误)");
        ReadNextToken();
    }
}

        treeNode   program(){
	            treeNode  t=programHead();
	            treeNode  q=declarePart();
	            treeNode  s=programBody();

                treeNode root = newSpecificNode(NodeKind.ProK);
                if(root!=null)
	            {
		            root.lineno = 0;//没有行号
		            if(t!=null) root.child[0] = t;
	                  else printError("A program head is expected!");
	                if(q!=null) root.child[1] = q;
	                if(s!=null) root.child[2] = s;
	                  else printError("A program body is expected!");
	            }
	            match(LexType.DOT);

	            return root;
            }
   treeNode programHead(){
        treeNode t = newSpecificNode(NodeKind.PheadK);
	    match(LexType.PROGRAM);
        if((t!=null)&&(token.Lex==LexType.ID))
	    {   
		    t.lineno =0;//声明性节点没有行号
		    t.name[0]=token.Sem;
	    }
        match(LexType.ID);
        return t;
    }
	treeNode  declarePart(){
	         treeNode  typeP = newSpecificNode(NodeKind.TypeK);  
	         treeNode  pp = typeP;  
	 
	         if(typeP!=null)
	         {
		         typeP.lineno =line0;//类型声明的标志节点也没有行号
		         treeNode  tp1 = typeDec();
	             if(tp1!=null)
		             typeP.child[0] = tp1;
		         else
                 {
                     typeP = null;
		         }
	         }
	         /*变量*/
	         treeNode varP = newSpecificNode(NodeKind.VarK);
             varP.lineno = line0;
	 
	         if(varP != null){
		         varP.lineno = line0;//变量标志节点
		         treeNode  tp2 = varDec();
		         if(tp2 != null)
	                  varP.child[0] = tp2;
		         else 
		         {
		             varP=null;
		         }
             }
	         /*函数*/
	         treeNode s = procDec();
     
	         if(s==null){}
	 
	         if(varP==null){varP=s;}
	 
             if(typeP==null){pp=typeP=varP;}
	 
	         if(typeP!=varP)
	         {
		        typeP.sibling = varP;
                typeP = varP;
	         }
	         if(varP!=s)
	         {
		        varP.sibling = s;
		        varP = s;
	         }
	         return pp;
        }
   treeNode typeDec(){
	            treeNode  t = null;
	            switch (token.Lex)
	            { 
	              case LexType.TYPE: t = typeDeclaration(); break;
	              case LexType.VAR:
	              case LexType.PROCEDURE:
                  case LexType.BEGIN: break;
                  default :
		              ReadNextToken();
		              printError(token.lineshow+":Unexpected token is here!");
		              break;
	             }
	            return t;
            }
       treeNode typeDeclaration(){
	      match(LexType.TYPE);
	      treeNode  t = typeDecList();
	      if (t==null )
	        {
                printError(token+":a type declaration is expected!");
	        }
	        return t;
        }
         treeNode typeDecList(){
	        treeNode t = newSpecificNode(NodeKind.DecK);
            if (t != null)
            {
                t.lineno = line0;
                typeId(t);
                match(LexType.EQ);
                typeName(t);////////////////////////////////////////////////error 
                match(LexType.SEMI);
                treeNode p = typeDecMore();
                if (p != null)
                    t.sibling = p;
            }
            else {
                window.WriteLine("t is null 488");
            }
            return t;
        }
      treeNode   typeDecMore()
            {
	            treeNode  t=null;
                switch(token.Lex){
	            case LexType.VAR:         
	            case LexType.PROCEDURE:
	            case LexType.BEGIN:
		            break;
	            case LexType.ID:
		            t = typeDecList();
		            break;
	            default:
		              ReadNextToken();
		              printError(token.lineshow+":unexpected token is here!");
		              break;
	            }
	            return t;
            }
        void typeId(treeNode  t)
            {
	            int tnum = (t.idnum);
	            if ((token.Lex==LexType.ID)&&(t!=null))
	            {
	                t.name[tnum] =token.Sem;
		            tnum = tnum+1;
	            }
	            t.idnum = tnum;
	            match(LexType.ID);
            }
        void typeName(treeNode  t){
                  if (t!=null )
	                  switch (token.Lex)
		              {
		              case LexType.INTEGER:
		              case LexType.CHAR1:    baseType(t);break;
                      case LexType.ARRAY:
                      case LexType.RECORD: structureType(t); break;
                      case LexType.ID:      
			                  t.kind.dec = DecKind.IdK;
				              t.attr.type_name=token.Sem;
			                  match(LexType.ID);
			                  break;
		              default:
			              ReadNextToken();
			              printError(token.lineshow+":unexpected token is here!");
		                  break;
		              } 
            }
        void baseType(treeNode  t){
	            switch(token.Lex)
	            {
	            case LexType.INTEGER:  match(LexType.INTEGER);
	                           t.kind.dec = DecKind.IntegerK;
				               break;

	            case LexType.CHAR1:     match(LexType.CHAR1);
		                       t.kind.dec = DecKind.CharK;
				               break;

                default:
	  		              ReadNextToken();
			              printError(token.lineshow+"unexpected token is here!");
		                  break;
	            }
            }
        void structureType(treeNode  t)
            {
	            switch(token.Lex)
	            {
	            case LexType.ARRAY:    
		            arrayType(t);               
		            break;
                case LexType.RECORD:   
		            t.kind.dec = DecKind.RecordK;
		            recType(t);
	                break;
                default:
		            ReadNextToken();
		            printError(token.lineshow+":unexpected token is here!");
		            break;
	            }
            }
        //将字符串转化成数字
        public  int  StrToInt(string str)
        {
            int length = str.Length;
            char c;
            int sum = 0;
            int count = 0;
            for (int j = 0; j < length; j++)
            {
                c = str.ElementAt(j);
                switch (c)
                {
                    case '0': count = 0; break;
                    case '1': count = 1; break;
                    case '2': count = 2; break;
                    case '3': count = 3; break;
                    case '4': count = 4; break;
                    case '5': count = 5; break;
                    case '6': count = 6; break;
                    case '7': count = 7; break;
                    case '8': count = 8; break;
                    case '9': count = 9; break;
                }
                sum = sum * 10 + count;
            }
            return sum;
        }
        void  arrayType(treeNode  t)
        {
             match(LexType.ARRAY);
	         match(LexType.LMIDPAREN);
             if (token.Lex==LexType.INTC)
	         {
		         t.attr.ArrayAttr.low = StrToInt(token.Sem);//将字符串数字转化成整形的数字
	         }
	         match(LexType.INTC);
             match(LexType.UNDERANGE);
             if (token.Lex == LexType.INTC)
	         {
		         t.attr.ArrayAttr.up = StrToInt(token.Sem);
	         }
             match(LexType.INTC);
             match(LexType.RMIDPAREN);
             match(LexType.OF);
             baseType(t);
             t.attr.ArrayAttr.childtype = t.kind.dec;
	         t.kind.dec = DecKind.ArrayK;
        }
        void  recType(treeNode  t)
                {
	                treeNode  p = null;
	                match(LexType.RECORD);
                    p = fieldDecList();
	                if(p!=null)
		                t.child[0] = p;
	                else
		                printError(token.lineshow+":a record body is requested!");
                    match(LexType.END);
                }
       treeNode   fieldDecList()
            {

                treeNode t = newSpecificNode(NodeKind.DecK);
	            treeNode  p = null;
	            if (t!=null)
	            {
	                t.lineno = line0;
		            switch(token.Lex)
		            {
		            case LexType.INTEGER:
                    case LexType.CHAR1:
                       baseType(t);
	                   idList(t);
                       match(LexType.SEMI);
	                   p = fieldDecMore();
	                   break;
                    case LexType.ARRAY: 
	                   arrayType(t);
	                   idList(t);
                       match(LexType.SEMI);
	                   p = fieldDecMore();
	                   break;
                    default:
		               ReadNextToken();
		               printError(token.lineshow+":unexpected token is here!");
		               break;
		            }
	                t.sibling = p;
	            }
	            return t;
            }
      treeNode fieldDecMore()
            {
                treeNode  t = null;   
	            switch(token.Lex)
	            {
	            case LexType.END: break;
                case LexType.INTEGER:
                case LexType.CHAR1:
                case LexType.ARRAY: 
		            t=fieldDecList();
		            break;
	            default:
		            ReadNextToken();
		            printError(token.lineshow+":unexpected token is here!");
		            break;
	            }
	            return t;
            }
        void  idList(treeNode  t)
            {
	            if (token.Lex==LexType.ID)
	            {
		            t.name[(t.idnum)] =token.Sem;
		            match(LexType.ID);
		            t.idnum = (t.idnum) + 1;
	            }
	            idMore(t);
            }
         void  idMore(treeNode  t)
                {
	                switch(token.Lex)
	                {
	                case LexType.SEMI:  break;
	                case LexType.COMMA: 
		                match(LexType.COMMA);
		                idList(t);
		                break;
	                default:
	                    ReadNextToken();
		                printError(token.lineshow+":unexpected token is here!");
		                break;
	                }
                }
        treeNode  varDec()
            {
	            treeNode  t = null;
	            switch(token.Lex)
	            {
	            case LexType.PROCEDURE:
	            case  LexType.BEGIN:     break;
	            case LexType.VAR:
		            t = varDeclaration();
		            break;
	            default:
	                ReadNextToken();
		            printError(token.lineshow+":unexpected token is here!");
		            break;
	            }
	            return t;
            }
         treeNode   varDeclaration()
            {
	            match(LexType.VAR);
	            treeNode  t = varDecList();
                if(t==null)
		            printError(token.lineshow+":a var declaration is expected!");
	            return t;
            }
        treeNode   varDecList()
            {
	            treeNode  t = newSpecificNode(NodeKind.DecK);
	            treeNode  p = null;

	            if ( t != null )
	            {
		            t.lineno = line0;
		            typeName(t);
	                varIdList(t);
	                match(LexType.SEMI);
                    p = varDecMore();
	                t.sibling = p;
	            }
	            return t;
            }
        treeNode   varDecMore()
            {
	            treeNode  t =null;

	            switch(token.Lex)
	            {
	            case LexType.PROCEDURE:
                case LexType.BEGIN:
		                break;
                case LexType.INTEGER:
                case LexType.CHAR1:
                case LexType.ARRAY:
                case LexType.RECORD:
                case LexType.ID:
		            t = varDecList();
		            break;
	            default:
		            ReadNextToken();
		            printError(token.lineshow+":unexpected token is here!");
		            break;
	            }
	            return t;
            }
        void varIdList(treeNode t)
            {
	            if (token.Lex==LexType.ID)
	            {
                    t.name[(t.idnum)] =token.Sem;
                    match(LexType.ID);
		            t.idnum =(t.idnum ) + 1;
	            }
	            else 
	            {
		            printError(token.lineshow+"：a varid is expected here!");
		            ReadNextToken();
	            }
	            varIdMore(t);
            }
         void  varIdMore(treeNode  t)
                {
	                switch(token.Lex)
	                {
	                case LexType.SEMI:  break;
	                case LexType.COMMA:
		                match(LexType.COMMA);
		                varIdList(t);
		                break;
	                default:
		                ReadNextToken();
		                printError(token.lineshow+"：unexpected token is here!");
		                break;
	                }
                }
        treeNode  procDec()
            {
                treeNode t = null;
	            switch(token.Lex)
	            {
	            case LexType.BEGIN:   break;
	            case LexType.PROCEDURE:
		            t = procDeclaration();
		            break;
	            default:
		            ReadNextToken();
		            printError(token.lineshow+":unexpected token is here!");
		            break;
	            }
	            return t;
            }
       treeNode  procDeclaration()
            {
                treeNode t = newSpecificNode(NodeKind.ProcDecK);
	            match(LexType.PROCEDURE);
	            if (t!=null)
	            {
		            t.lineno = line0;
		            if (token.Lex==LexType.ID)
		            {
			            t.name[0]=token.Sem;
			            (t.idnum)++;
			            match(LexType.ID);
		            }
		            match(LexType.LPAREN);
		            paramList(t);
		            match(LexType.RPAREN);
                    match(LexType.SEMI);
		            t.child[1] = procDecPart();
		            t.child[2] = procBody();
		            t.sibling = procDec();
	            }
	            return t;
         }
         void  paramList(treeNode  t)     
                    {
	                    treeNode  p = null;
	
	                    switch(token.Lex)
	                    {
	                    case LexType.RPAREN:  break;
	                    case LexType.INTEGER:
                        case LexType.CHAR1:
                        case LexType.ARRAY:
                        case LexType.RECORD:
                        case LexType.ID:
                        case LexType.VAR:
		                    p = paramDecList();
		                    t.child[0] = p;
		                    break;
	                    default:
		                    ReadNextToken();
		                    printError(token.lineshow+":unexpected token is here!");
		                    break;
	                    }
                 }
         treeNode paramDecList()
            {
	            treeNode  t = param();
	            treeNode  p = paramMore();
	            if (p!=null)
	            {
		            t.sibling = p;
	            }
	            return t;
            }
       treeNode paramMore(){
	        treeNode  t = null;
	        switch(token.Lex)
	        {
	        case LexType.RPAREN:   break;
	        case LexType.SEMI:
		        match(LexType.SEMI);
		        t = paramDecList();
		        if (t==null)
			        printError(token.lineshow+":a param declaration is request!");
		        break;
            default:
		        ReadNextToken();
		        printError(token.lineshow+":unexpected token is here!");
		        break;
	        }
	        return t;
        }
        treeNode  param()
            {
	            treeNode t = newSpecificNode(NodeKind.DecK);
	            if (t!=null)
	            {
		            t.lineno = line0;
		            switch(token.Lex)
		            {
	                 case LexType.INTEGER:
	                 case  LexType.CHAR1:
	                 case  LexType.ARRAY:
	                 case  LexType.RECORD:
	                 case  LexType.ID:
	    	             t.attr.ProcAttr.paramt = ParamType.valparamType;
			             typeName(t);
	    	             formList(t);
			             break;
		             case LexType.VAR:
			             match(LexType.VAR);
			             t.attr.ProcAttr.paramt = ParamType.varparamType;
			             typeName(t);
			             formList(t);
			             break;
                     default:
			             ReadNextToken();
			             printError(token.lineshow+":unexpected token is here!");
		                 break;
		            }
	            }
	            return t;
            }
             void  formList(treeNode t)
            {
	            if (token.Lex==LexType.ID)
	            {
		            t.name[(t.idnum)] =token.Sem;
		            t.idnum = (t.idnum) + 1;
		            match(LexType.ID);
	            }
	            fidMore(t);   
            }
        void  fidMore(treeNode t)
        {
	        switch(token.Lex)
	        {
	        case LexType.SEMI:
	        case LexType.RPAREN:   break;
	        case LexType.COMMA:
		        match(LexType.COMMA);
		        formList(t);
		        break;
	        default:
		        ReadNextToken();
		        printError(token.lineshow+":unexpected token is here!");
		        break;
	        }
        }
    treeNode   procDecPart()
            {
                 treeNode t = declarePart();
	             return t;
            }

    treeNode  procBody()
        {
	        treeNode t = programBody();
	        if (t==null)
	            printError(token.lineshow+":a program body is requested!");
	        return t;
        }
 treeNode  programBody()
        {
	        treeNode t = newSpecificNode(NodeKind.StmLK);
    
	        match(LexType.BEGIN);
	        if(t!=null)
	        {
		        t.lineno = line0;
		        t.child[0] = stmList();
	        }
            match(LexType.END);
            return t;
        }
 treeNode   stmList()
        {
	        treeNode t = stm();
            treeNode p = stmMore();
	        if(t!=null)
		        if ( p!= null)
			        t.sibling = p;
	        return t;
        }

 treeNode   stmMore()
{
	treeNode t = null;
	switch(token.Lex)
	{
	case LexType.ELSE:
	case LexType.FI:
	case LexType.END:
	case LexType.ENDWH:	break;
	case LexType.SEMI:
		match(LexType.SEMI);
		t = stmList();
		break;
	default:
		ReadNextToken();
		printError(token.lineshow+":unexpected token is here!");
		break;
	}
	return t;
}

 treeNode   stm()
        {
	
	        treeNode t = null;
	        switch(token.Lex)
	        {
	        case LexType.IF:  
		        t = conditionalStm();
		        break;
	        case LexType.WHILE:
		        t = loopStm();
		        break;
	        case LexType.READ:
		        t = inputStm();
		        break;
	        case LexType.WRITE:
		        t = outputStm();
		        break;
	        case LexType.RETURN:
		        t = returnStm();
		        break;
	        case LexType.ID:
		        temp_name = token.Sem;
		        match(LexType.ID);              
                t = assCall();
		        break;
	        default:
		        ReadNextToken();
		        printError(token.lineshow+":unexpected token is here!");
		        break;
	        }
	        return t;
        }
 treeNode   assCall()
{
	        treeNode t = null;
	        switch(token.Lex)
	        {
	        case LexType.ASSIGN:
	        case LexType.LMIDPAREN:
	        case LexType.DOT:
		        t = assignmentRest();
		        break;
	        case LexType.LPAREN:
		        t = callStmRest();
		        break;
	        default:
		        ReadNextToken();
		        printError(token.lineshow+":unexpected token is here!");
		        break;
	        }
	        return t;
}

 treeNode   assignmentRest(){
	treeNode t = newStmtNode(StmtKind.AssignK);//赋值语句节点，子节点：变量节点和表达式。
	if(t!=null)
    {
		t.lineno = line0;
		treeNode child1 = newExpNode(ExpKind.VariK);
		if(child1!=null)
		{
			child1.lineno = line0;
			child1.name[0]=temp_name;
			(child1.idnum)++;
			variMore(child1);
			t.child[0] = child1;
		}	
		match(LexType.ASSIGN);
		t.child[1] = exp(); 
				
	}
	return t;
}
 treeNode   conditionalStm()
{
	treeNode t = newStmtNode(StmtKind.IfK);
	match(LexType.IF);
	if(t!=null)  
	{
		t.lineno = line0;
		t.child[0] = exp();
	}
	match(LexType.THEN);
	if(t!=null)  t.child[1] = stmList();
	if(token.Lex==LexType.ELSE)
	{
		match(LexType.ELSE);
		if(t!=null)   
			t.child[2] = stmList();
	}
	match(LexType.FI);
	return t;
}

 treeNode   loopStm()
{
	treeNode t = newStmtNode(StmtKind .WhileK);/////while节点,子节点:条件表达式和语句序列。
	match(LexType .WHILE);
	if (t!=null)  
	{
		t.lineno = line0;
		t.child[0] = exp();
	    match(LexType.DO);
	    t.child[1] = stmList();
	    match(LexType.ENDWH);
	}
	return t;
}

 treeNode   inputStm()
{
	treeNode t = newStmtNode(StmtKind.ReadK);
	match(LexType.READ);
	match(LexType.LPAREN);
	if((t!=null)&&(token.Lex==LexType.ID))	
	{
		t.lineno = line0;
		t.name[0] =token.Sem;
        (t.idnum)++;
	}
	match(LexType.ID);
	match(LexType.RPAREN);
	return t;
}
 treeNode   outputStm()
{
	treeNode t = newStmtNode(StmtKind.WriteK);
	match(LexType.WRITE);
	match(LexType.LPAREN);
	if(t!=null)  
	{
		t.lineno = line0;
		t.child[0] = exp();
	}
	match(LexType.RPAREN);
	return t;
}

 treeNode   returnStm()
{
	treeNode t = newStmtNode(StmtKind.ReturnK);
	match(LexType.RETURN);
	if(t!=null)
		t.lineno = line0;
	return t;
}

 treeNode   callStmRest()
{
	treeNode t=newStmtNode(StmtKind.CallK);
	match(LexType.LPAREN);
	if(t!=null)  
	{
		t.lineno = line0;		
		treeNode child0 = newExpNode(ExpKind.VariK); 
		if(child0!=null)
		{
			child0.lineno = line0;
			child0.name[0]=temp_name;
			(child0.idnum)++;
			t.child[0] = child0;
		}
		t.child[1] = actParamList();
	}
	match(LexType.RPAREN);
	return t;
}
 treeNode   actParamList()
{
	treeNode t = null;

	switch(token.Lex)
	{
	case LexType.RPAREN:        break;
	case LexType.ID:
	case LexType.INTC:
		t =exp();
		if(t!=null)
			t.sibling = actParamMore();
		break;
	default:
		ReadNextToken();
		printError(token.lineshow+":unexpected token is here!");
		break;
	}
	return t;
}
 treeNode   actParamMore()
{
	treeNode t = null;
	switch(token.Lex)
	{
	case LexType.RPAREN:   break;
	case LexType.COMMA:
		match(LexType.COMMA);
		t = actParamList();
		break;
	default:	
		ReadNextToken();
		printError(token.lineshow+":unexpected token is here!");
		break;
	}
	return t;
}
 treeNode   exp(){
   treeNode t = simple_exp();
   if ((token.Lex==LexType.LT)||(token.Lex==LexType.EQ)){
        treeNode p = newExpNode(ExpKind.OpK);
        if (p!=null) 
	    {
          p.lineno = line0;
	      p.child[0] = t;
          p.attr.ExpAttr.op = token.Lex;
          t = p;
        }
        match(token.Lex);
        if (t!=null)
          t.child[1] = simple_exp();
  }
  return t;
}

 treeNode   simple_exp()
        {
          treeNode t = term();
          while ((token.Lex==LexType.PLUS)||(token.Lex==LexType.MINUS))

          {
	        treeNode p = newExpNode(ExpKind.OpK);
            if (p!=null) 
	        {
              p.lineno = line0;
	          p.child[0] = t;
              p.attr.ExpAttr.op = token.Lex;
              t = p;
              match(token.Lex);
              t.child[1] = term();
            }
          }
          return t;
        }

 treeNode   term()
{
          treeNode t = factor();
          while ((token.Lex==LexType.TIMES)||(token.Lex==LexType.OVER)){
	        treeNode p = newExpNode(ExpKind.OpK);
            if (p!=null) 
	        {
              p.lineno= line0;
	          p.child[0] = t;
              p.attr.ExpAttr.op = token.Lex;
              t = p;
	        }
            match(token.Lex);
            p.child[1] = factor();
    
          }
          return t;
}
 treeNode   factor(){
  treeNode t = null;
  switch (token.Lex) 
  {
    case LexType.INTC :									
      t = newExpNode(ExpKind.ConstK);
      if ((t!=null) && (token.Lex==LexType.INTC))
	  {
		  t.lineno = line0;
		  t.attr.ExpAttr.val = StrToInt(token.Sem);
	  }
      match(LexType.INTC);
      break;
    case LexType.ID :	  
	  t = variable();
      break;
          //(
    case LexType.LPAREN :		
      match(LexType.LPAREN);					
      t = exp();
      match(LexType.RPAREN);					

      break;
    default:			
      ReadNextToken();
	  printError(token.lineshow+":unexpected token is here!");
	  break;
    }
  /* 函数返回表达式类型语法树节点t */
  return t;
}
 treeNode   variable()
{
	treeNode t = newExpNode(ExpKind.VariK);

	if ((t!=null) && (token.Lex==LexType.ID))
	{
		t.lineno = line0;
		t.name[0]=token.Sem;
        (t.idnum)++;
	}
	
	match(LexType.ID);
	variMore(t);
	return t;
}
		
void   variMore(treeNode t)
{
	switch(token.Lex)
	{	
	case LexType.ASSIGN:
	case LexType.TIMES:
	case LexType.EQ:
	case LexType.LT:
	case LexType.PLUS:
	case LexType.MINUS:
	case LexType.OVER:
	case LexType.RPAREN:
	case LexType.RMIDPAREN:
	case LexType.SEMI:
	case LexType.COMMA:
	case LexType.THEN:
	case LexType.ELSE:
	case LexType.FI:
	case LexType.DO:
	case LexType.ENDWH:
	case LexType.END:
		break;
	case LexType.LMIDPAREN:
		match(LexType.LMIDPAREN);
		t.child[0] = exp();

		t.attr.ExpAttr.varkind = VarKind.ArrayMembV;
		t.child[0].attr.ExpAttr.varkind = VarKind.IdV;
		match(LexType.RMIDPAREN);
		break;
	case LexType.DOT:
		match(LexType.DOT);
		t.child[0] = fieldvar();

		t.attr.ExpAttr.varkind = VarKind.FieldMembV;

		t.child[0].attr.ExpAttr.varkind = VarKind.IdV;
		break;
	default:
		ReadNextToken();
		printError(token.lineshow+":unexpected token is here!");
		break;
	}
}
 treeNode fieldvar()
{
	treeNode t = newExpNode(ExpKind.VariK);
	if ((t!=null) && (token.Lex==LexType.ID))
	  {
		  t.lineno = line0;
		  t.name[0]=token.Sem;
          (t.idnum)++;
	  }	
	match(LexType.ID);
	fieldvarMore(t);
	return t;
}
void   fieldvarMore(treeNode t )
{
	switch(token.Lex)
	{
	case LexType.ASSIGN:
	case LexType.TIMES:
	case LexType.EQ:
	case LexType.LT:
	case LexType.PLUS:
	case LexType.MINUS:
	case LexType.OVER:
	case LexType.RPAREN:
	case LexType.SEMI:
	case LexType.COMMA:
	case LexType.THEN:
	case LexType.ELSE:
	case LexType.FI:
	case LexType.DO:
	case LexType.ENDWH:
	case LexType.END:
		break;
	case LexType.LMIDPAREN:
		match(LexType.LMIDPAREN);
		
		t.child[0] = exp();
		t.child[0].attr.ExpAttr.varkind = VarKind.ArrayMembV;
		match(LexType.RMIDPAREN);
		break;
	default:
		ReadNextToken();
		printError(token.lineshow+":unexpected token is here!");
		break;
	}
}

    }
}
